import { Result } from '../../dto/result.type';
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { UseGuards } from '@nestjs/common';
import { GqlAuthGuard } from '../../guards/auth.guard';
import { StudentResult, StudentResults } from './dto/result-student.output';
import { StudentInput } from './dto/student.input';
import { StudentType } from './dto/student.type';
import { StudentService } from './student.service';
import { CurUserId } from '../../decorators/current-user.decorator';
import { PageInput } from '../../dto/page.input';
import { FindOptionsWhere, In, Like } from 'typeorm';
import { CardRecordService } from '../cardRecord/cardRecord.service';
import _ from 'lodash';
import { Student } from './models/student.entity';
import { OrderService } from '../order/order.service';

@Resolver(() => StudentType)
export class StudentResolver {
  constructor(
    private readonly studentService: StudentService,
    private readonly cardRecordService: CardRecordService,
    private readonly orderService: OrderService,
  ) {}

  @Mutation(() => Result, { description: '创建新学员' })
  async createStudent(@Args('params') params: StudentInput): Promise<Result> {
    return await this.studentService.createStudent(params);
  }

  @UseGuards(GqlAuthGuard)
  @Query(() => StudentResult)
  async getStudentInfo(@CurUserId() id: string): Promise<StudentResult> {
    const result = await this.studentService.findStudentById(id);
    if (result) {
      return {
        data: result,
        message: '获取成功',
        code: true,
      };
    }
    return {
      code: false,
      message: '用户信息不存在',
    };
  }

  @UseGuards(GqlAuthGuard)
  @Query(() => StudentResult)
  async getStudentInfoPc(@Args('id') id: string): Promise<StudentResult> {
    const result = await this.studentService.findStudentById(id);
    if (result) {
      return {
        data: result,
        message: '获取成功',
        code: true,
      };
    }
    return {
      code: false,
      message: '用户信息不存在',
    };
  }

  // 获取购买过自己课程的用户
  @UseGuards(GqlAuthGuard)
  @Query(() => StudentResult)
  async getStudentInfoWithOrg(@Args('id') id: string): Promise<StudentResult> {
    const result = await this.studentService.findStudentById(id);
    if (result) {
      return {
        data: result,
        message: '获取成功',
        code: true,
      };
    }
    return {
      code: false,
      message: '用户信息不存在',
    };
  }

  @UseGuards(GqlAuthGuard)
  @Mutation(() => StudentResult)
  async updateStudent(
    @Args('params') params: StudentInput,
    @CurUserId() userId: string,
  ): Promise<Result> {
    return await this.studentService.updateStudent(userId, params);
  }

  @UseGuards(GqlAuthGuard)
  @Query(() => StudentResults)
  async getStudents(
    @Args('page') page: PageInput,
    @Args('name', { nullable: true }) name?: string,
  ): Promise<StudentResults> {
    const { pageNum, pageSize } = page;
    const where: FindOptionsWhere<Student> = {};
    if (name) {
      where.name = Like(`%${name}%`);
    }
    const [results, total] = await this.studentService.findStudents({
      start: pageNum === 1 ? 0 : (pageNum - 1) * pageSize,
      length: pageSize,
      where,
    });
    return {
      data: results,
      page: {
        pageNum,
        pageSize,
        total,
      },
      message: '获取成功',
    };
  }

  @UseGuards(GqlAuthGuard)
  @Query(() => Result)
  async getCanReserveCourse(@CurUserId() userId: string): Promise<Result> {
    // 获取可以使用的消费卡
    const normalCardRecords =
      await this.cardRecordService.findNormalCardRecords(userId);
    if (!normalCardRecords || normalCardRecords.length === 0) {
      return {
        code: false,
        message: '未找到可约课程',
      };
    }
    // 获取消费卡可以预约的课程
    const res = _.uniqBy(
      normalCardRecords.map((item) => ({
        orgId: item.orgId,
        productId: item.productId,
        courseId: item.courseId,
      })),
      'courseId',
    );
    return {
      data: JSON.stringify(res),
      code: true,
      message: '获取成功',
    };
  }

  // 通过订单查询购买过的学员
  @UseGuards(GqlAuthGuard)
  @Query(() => StudentResults)
  async getStudentsByOrders(
    @Args('page') page: PageInput,
    @Args('orgId') orgId: string,
    @Args('name', { nullable: true }) name?: string,
  ): Promise<StudentResults> {
    const { pageNum, pageSize } = page;
    const [orders] = await this.orderService.findOrders({
      start: pageNum === 1 ? 0 : (pageNum - 1) * pageSize,
      length: pageSize,
      where: {
        orgId,
      },
    });
    const studentsId = orders.map((item) => item.createdBy);
    const where: FindOptionsWhere<Student> = {};
    if (name) {
      where.name = Like(`%${name}%`);
    }
    if (studentsId.length === 0) {
      return {
        data: [],
        page: {
          pageNum,
          pageSize,
          total: 0,
        },
        message: '获取成功',
      };
    }
    where.id = In(studentsId);
    const [results, total] = await this.studentService.findStudents({
      start: pageNum === 1 ? 0 : (pageNum - 1) * pageSize,
      length: pageSize,
      where,
    });
    return {
      data: results,
      page: {
        pageNum,
        pageSize,
        total,
      },
      message: '获取成功',
    };
  }
}
